/*
Copyright (C) 2015 Marien Raat

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <SFML/Graphics.hpp>
#include <lightingGenerator.h>
#include <string>

#define ONE_LAND_COLOR false

#define COLOR_WATER_DEEP sf::Color(0, 0, 110)
#define COLOR_WATER sf::Color(0, 0, 220)
#define COLOR_BEACH sf::Color(255, 255, 0)
#define COLOR_GRASS sf::Color(0, 255, 0)
#define COLOR_FOREST sf::Color(0, 150, 0)
#define COLOR_MOUNTAIN sf::Color(150, 150, 150)
#define COLOR_ICE sf::Color(255, 255, 255)

enum MapDisplayType {
  MAP_DISPLAY_TYPE_HEIGHTMAP,
  MAP_DISPLAY_TYPE_SIMPLE_MAP,
  MAP_DISPLAY_TYPE_LAND_MAP,
  MAP_DISPLAY_TYPE_LIGHTED_MAP
};

enum SmoothingType {
  SMOOTHING_TYPE_INTERPOLATE,
  SMOOTHING_TYPE_AVERAGE
};

class MapDisplayer {
public:
    MapDisplayer(sf::Vector2u size
		 , MapDisplayType mapDisplayType);

    void setMapDisplayType(MapDisplayType mapDisplayType);
    void setWaterDisplayed(bool value) { displayWater = value; }
    bool isWaterDisplayed() { return displayWater; }
    MapDisplayType getMapDisplayType();

    void updateDisplay();

    void setHeightmap(double *heightmap);
    void setWatermap(double *watermap);
    void setHeightmapPassSize(int passSize);
    void setSmoothingType(SmoothingType smoothingType);
    void setWaterLevel(double waterLevel);
    void setHeightModifierFunction(double (*modifierFunction)
                                   (double));
    double *heightmapCopy;

    void setNamesFont(sf::Font *namesFont);
    void setIslandName(std::string islandName);

    void setLandMap(bool *landMap);

    void setLightMap(Vec3f *lightmap);

    void updateHeightmapDisplay();
    void updateSimpleMapDisplay();
    void updateLandMapDisplay();
    void updateWaterDisplay();
    void updateLightMapDisplay();

    void draw(sf::RenderWindow *window);
private:
    MapDisplayType mapDisplayType;
    SmoothingType smoothingType;
    double *heightmap;
    double waterLevel;
    double (*modifierFunction)(double);

    bool *landMap;

    bool displayWater = true;
    double *normalizedWatermap;

    int passSize;
    sf::Vector2u size;
    sf::Image heightmapImage, simpleMapImage, landMapImage,
    waterImage, lightMapImage;

    Vec3f *lightmap;

    sf::Texture displayTexture;
    sf::Sprite displaySprite;
    sf::Texture waterTexture;
    sf::Sprite waterSprite;

    sf::Text islandNameText;

    sf::Color getSimpleMapColor(double value);
    sf::Color getLinearInterpolate(sf::Color c1, sf::Color c2,
                                   double weight);
    double getModifiedValue(double aboveWater);
};
